﻿Imports System.Collections.ObjectModel
Imports System.ComponentModel

#Region " LocalUserクラス "
''' <summary>
''' ローカルのユーザーを表すクラスです。
''' </summary>
''' <remarks></remarks>
Public NotInheritable Class LocalUser
  Inherits DirectoryObject
  Implements IUser

#Region " フレンドコンストラクター "
  ''' <summary>
  ''' <see cref="DirectoryEntry"/> を指定して <see cref="LocalUser"/> クラスの新しいインスタンスを初期化します。
  ''' </summary>
  ''' <param name="entry"><see cref="DirectoryEntry"/>。</param>
  ''' <remarks></remarks>
  Friend Sub New(entry As DirectoryEntry)
    MyBase.New(entry)
  End Sub
#End Region

#Region " パブリックプロパティ "
  ''' <summary>
  ''' アカウントが無効かどうかを取得します。
  ''' </summary>
  ''' <value></value>
  ''' <returns>アカウントが無効かどうかを示す値。</returns>
  ''' <remarks></remarks>
  Public Property Disabled As Boolean Implements IUser.Disabled
    Get
      If MyBase.IsDisposed Then
        Throw New ObjectDisposedException(Me.GetType().Name)
      End If
      Return DirectCast(MyBase.Entry.NativeObject, IADsUser).AccountDisabled
    End Get
    Set(value As Boolean)
      If MyBase.IsDisposed Then
        Throw New ObjectDisposedException(Me.GetType().Name)
      End If
      DirectCast(MyBase.Entry.NativeObject, IADsUser).AccountDisabled = value
    End Set
  End Property

  ''' <summary>
  ''' フルネームを取得または設定します。
  ''' </summary>
  ''' <value></value>
  ''' <returns>フルネーム。</returns>
  ''' <remarks></remarks>
  Public Property FullName As String Implements IUser.FullName
    Get
      If MyBase.IsDisposed Then
        Throw New ObjectDisposedException(Me.GetType().Name)
      End If
      Return DirectCast(MyBase.Entry.Properties.Item("FullName").Value, String)
    End Get
    Set(value As String)
      If MyBase.IsDisposed Then
        Throw New ObjectDisposedException(Me.GetType().Name)
      End If
      MyBase.Entry.Properties.Item("FullName").Value = value
    End Set
  End Property

  ''' <summary>
  ''' <see cref="Entry"/> の ADSI User オブジェクトを取得します。
  ''' </summary>
  ''' <value></value>
  ''' <returns><see cref="Entry"/> の ADSI User オブジェクト。</returns>
  ''' <remarks></remarks>
  Public ReadOnly Property Native As IADsUser Implements IUser.Native
    Get
      If MyBase.IsDisposed Then
        Throw New ObjectDisposedException(Me.GetType().Name)
      End If
      Return DirectCast(MyBase.Entry.NativeObject, IADsUser)
    End Get
  End Property
#End Region
End Class
#End Region

#Region " DomainUserクラス "
''' <summary>
''' ドメインのユーザーを表すクラスです。
''' </summary>
''' <remarks></remarks>
<DataObject()>
Public NotInheritable Class DomainUser
  Inherits DomainObject
  Implements IUser

#Region " プライベートフィールド "
  Private ReadOnly _name As String
#End Region

#Region " フレンドコンストラクター "
  ''' <summary>
  ''' <see cref="DirectoryEntry"/> を指定して <see cref="DomainUser"/> クラスの新しいインスタンスを初期化します。
  ''' </summary>
  ''' <param name="entry"><see cref="DirectoryEntry"/>。</param>
  ''' <remarks></remarks>
  Friend Sub New(entry As DirectoryEntry)
    MyBase.New(entry)
    _name = entry.Properties.Item("sAMAccountName").Value.ToString()
  End Sub
#End Region

#Region " パブリックプロパティ "
  ''' <summary>
  ''' 電子メールを取得または設定します。
  ''' </summary>
  ''' <value></value>
  ''' <returns>電子メール。</returns>
  ''' <remarks></remarks>
  Public Property EmailAddress As String
    Get
      If MyBase.IsDisposed Then
        Throw New ObjectDisposedException(Me.GetType().Name)
      End If
      Return DirectCast(MyBase.Entry.Properties.Item("mail").Value, String)
    End Get
    Set(value As String)
      If MyBase.IsDisposed Then
        Throw New ObjectDisposedException(Me.GetType().Name)
      End If
      MyBase.Entry.Properties.Item("mail").Value = value
    End Set
  End Property

  ''' <summary>
  ''' アカウントが無効かどうかを取得または設定します。
  ''' </summary>
  ''' <value></value>
  ''' <returns>アカウントが無効かどうかを示す値。</returns>
  ''' <remarks></remarks>
  Public Property Disabled As Boolean Implements IUser.Disabled
    Get
      If MyBase.IsDisposed Then
        Throw New ObjectDisposedException(Me.GetType().Name)
      End If
      Return DirectCast(MyBase.Entry.NativeObject, IADsUser).AccountDisabled
    End Get
    Set(value As Boolean)
      If MyBase.IsDisposed Then
        Throw New ObjectDisposedException(Me.GetType().Name)
      End If
      DirectCast(MyBase.Entry.NativeObject, IADsUser).AccountDisabled = value
    End Set
  End Property

  ''' <summary>
  ''' 表示用の名前を取得します。
  ''' </summary>
  ''' <value></value>
  ''' <returns>表示用の名前。</returns>
  ''' <remarks></remarks>
  Public ReadOnly Property DisplayName As String
    Get
      Return MyBase.Name
    End Get
  End Property

  ''' <summary>
  ''' 名を取得または設定します。
  ''' </summary>
  ''' <value></value>
  ''' <returns>名。</returns>
  ''' <remarks></remarks>
  Public Property FirstName As String
    Get
      If MyBase.IsDisposed Then
        Throw New ObjectDisposedException(Me.GetType().Name)
      End If
      Return DirectCast(MyBase.Entry.Properties.Item("givenName").Value, String)
    End Get
    Set(value As String)
      If MyBase.IsDisposed Then
        Throw New ObjectDisposedException(Me.GetType().Name)
      End If
      MyBase.Entry.Properties.Item("givenName").Value = value
    End Set
  End Property

  ''' <summary>
  ''' 表示名を取得または設定します。
  ''' </summary>
  ''' <value></value>
  ''' <returns>表示名。</returns>
  ''' <remarks></remarks>
  Public Property FullName As String Implements IUser.FullName
    Get
      If MyBase.IsDisposed Then
        Throw New ObjectDisposedException(Me.GetType().Name)
      End If
      Return DirectCast(MyBase.Entry.Properties.Item("displayName").Value, String)
    End Get
    Set(value As String)
      If MyBase.IsDisposed Then
        Throw New ObjectDisposedException(Me.GetType().Name)
      End If
      MyBase.Entry.Properties.Item("displayName").Value = value
    End Set
  End Property

  ''' <summary>
  ''' 姓を取得または設定します。
  ''' </summary>
  ''' <value></value>
  ''' <returns>姓。</returns>
  ''' <remarks></remarks>
  Public Property LastName As String
    Get
      If MyBase.IsDisposed Then
        Throw New ObjectDisposedException(Me.GetType().Name)
      End If
      Return DirectCast(MyBase.Entry.Properties.Item("sn").Value, String)
    End Get
    Set(value As String)
      If MyBase.IsDisposed Then
        Throw New ObjectDisposedException(Me.GetType().Name)
      End If
      MyBase.Entry.Properties.Item("sn").Value = value
    End Set
  End Property

  ''' <summary>
  ''' アカウント名を取得します。
  ''' </summary>
  ''' <value></value>
  ''' <returns>アカウント名。</returns>
  ''' <remarks></remarks>
  Public Overrides ReadOnly Property Name As String
    Get
      Return _name
    End Get
  End Property

  ''' <summary>
  ''' <see cref="Entry"/> の ADSI User オブジェクトを取得します。
  ''' </summary>
  ''' <value></value>
  ''' <returns><see cref="Entry"/> の ADSI User オブジェクト。</returns>
  ''' <remarks></remarks>
  Public ReadOnly Property Native As IADsUser Implements IUser.Native
    Get
      If MyBase.IsDisposed Then
        Throw New ObjectDisposedException(Me.GetType().Name)
      End If
      Return DirectCast(MyBase.Entry.NativeObject, IADsUser)
    End Get
  End Property

  ''' <summary>
  ''' 事業所を取得または設定します。
  ''' </summary>
  ''' <value></value>
  ''' <returns>事業所。</returns>
  ''' <remarks></remarks>
  Public Property OfficeName As String
    Get
      If MyBase.IsDisposed Then
        Throw New ObjectDisposedException(Me.GetType().Name)
      End If
      Return DirectCast(MyBase.Entry.Properties.Item("physicalDeliveryOfficeName").Value, String)
    End Get
    Set(value As String)
      If MyBase.IsDisposed Then
        Throw New ObjectDisposedException(Me.GetType().Name)
      End If
      MyBase.Entry.Properties.Item("physicalDeliveryOfficeName").Value = value
    End Set
  End Property

  ''' <summary>
  ''' プライマリ グループ ID を取得します。
  ''' </summary>
  ''' <value></value>
  ''' <returns>プライマリ グループ ID。</returns>
  ''' <remarks></remarks>
  Public ReadOnly Property PrimaryGroupId As Integer
    Get
      If MyBase.IsDisposed Then
        Throw New ObjectDisposedException(Me.GetType().Name)
      End If
      Return Convert.ToInt32(MyBase.Entry.Properties.Item("primaryGroupID").Value)
    End Get
  End Property

  ''' <summary>
  ''' 電話番号を取得または設定します。
  ''' </summary>
  ''' <value></value>
  ''' <returns>電話番号。</returns>
  ''' <remarks></remarks>
  Public Property TelephoneNumber As String
    Get
      If MyBase.IsDisposed Then
        Throw New ObjectDisposedException(Me.GetType().Name)
      End If
      Return DirectCast(MyBase.Entry.Properties.Item("telephoneNumber").Value, String)
    End Get
    Set(value As String)
      If MyBase.IsDisposed Then
        Throw New ObjectDisposedException(Me.GetType().Name)
      End If
      MyBase.Entry.Properties.Item("telephoneNumber").Value = value
    End Set
  End Property
#End Region

#Region " パブリックメソッド "
  ''' <summary>
  ''' 指定したアカウント名のユーザーを検索します。このメソッドはデータバインド用です。
  ''' </summary>
  ''' <param name="name">アカウント名。</param>
  ''' <returns>ユーザー。</returns>
  ''' <remarks></remarks>
  <DataObjectMethod(DataObjectMethodType.Select)>
  Public Shared Function FindByName(name As String) As DomainUser
    Return DirectCast(DirectoryAccess.FindDirectoryObject(name, CategoryType.User), DomainUser)
  End Function

  ''' <summary>
  ''' 指定したユーザーの所属するグループを取得します。このメソッドはデータバインド用です。
  ''' </summary>
  ''' <param name="userName">ユーザーのアカウント名。</param>
  ''' <returns>ユーザーの所属するグループ。</returns>
  ''' <remarks></remarks>
  <DataObjectMethod(DataObjectMethodType.Select)>
  Public Shared Function GetBelongGroups(userName As String) As ReadOnlyCollection(Of String)
    Dim user = FindByName(userName)   'ユーザーを検索
    Return DirectoryAccess.GetBelongGroups(user)  'ユーザーの所属するグループを取得
  End Function

  ''' <summary>
  ''' ユーザーの一覧を取得します。このメソッドはデータバインド用です。
  ''' </summary>
  ''' <returns>ユーザーの一覧。</returns>
  ''' <remarks></remarks>
  <DataObjectMethod(DataObjectMethodType.Select)>
  Public Shared Function GetUsers() As IList(Of DomainUser)
    Return DirectoryAccess.GetUsers(Of DomainUser)()  'ユーザーを取得
  End Function

  ''' <summary>
  ''' 表示用の名前を返します。
  ''' </summary>
  ''' <returns>表示用の名前。</returns>
  ''' <remarks></remarks>
  Public Overrides Function ToString() As String
    Return Me.DisplayName
  End Function
#End Region
End Class
#End Region
